#include "gamestateprocessor.h"
#include "incrementalgamestateparser.h"
#include <QDebug>
#include <QJsonDocument>
#include <QCoreApplication>

GameStateProcessor::GameStateProcessor(QObject *parent)
    : QObject(nullptr)  // 不设置parent，避免线程亲和性问题
    , m_thread(new QThread())  // 也不设置parent
    , m_processTimer(nullptr)  // 在线程内创建
    , m_running(false)
    , m_processedCount(0)
    , m_lastProcessTime(0)
    , m_incrementalParser(nullptr)
    , m_incrementalParsingEnabled(true)  // 默认启用增量解析
{
    Q_UNUSED(parent)  // 忽略parent参数

    // 注册自定义类型，支持跨线程信号槽传递
    qRegisterMetaType<RenderReadyGameData>("RenderReadyGameData");

    // 连接线程信号，在线程内部创建和设置所有对象
    connect(m_thread, &QThread::started, this, [this]() {
        qDebug() << "GameStateProcessor: 处理线程已启动，创建内部对象";
        qDebug() << "当前线程ID:" << QThread::currentThreadId();

        // 在正确的线程中创建定时器和解析器（无parent，避免线程冲突）
        m_processTimer = new QTimer();
        m_incrementalParser = new IncrementalGameStateParser();

        // 设置定时器，使用高精度定时，确保与渲染节拍一致
        m_processTimer->setInterval(16); // 60 FPS处理频率
        m_processTimer->setTimerType(Qt::PreciseTimer);
        connect(m_processTimer, &QTimer::timeout, this, &GameStateProcessor::processQueue);

        qDebug() << "GameStateProcessor: 准备启动定时器";
        m_processTimer->start();
        qDebug() << "GameStateProcessor: 定时器已启动";
        qDebug() << "定时器活跃状态:" << m_processTimer->isActive();
        qDebug() << "定时器间隔:" << m_processTimer->interval();

        // 测试立即调用一次processQueue
        qDebug() << "GameStateProcessor: 测试立即调用processQueue";
        processQueue();
    });

    connect(m_thread, &QThread::finished, this, [this]() {
        qDebug() << "GameStateProcessor: 处理线程已停止";
        if (m_processTimer) {
            m_processTimer->stop();
            delete m_processTimer;
            m_processTimer = nullptr;
        }
        if (m_incrementalParser) {
            delete m_incrementalParser;
            m_incrementalParser = nullptr;
        }
    });
}

GameStateProcessor::~GameStateProcessor()
{
    // 安全地停止线程，避免析构函数中的死锁
    if (m_running) {
        m_running = false;
        m_queueCondition.wakeAll();

        if (m_thread && m_thread->isRunning()) {
            m_thread->quit();
            if (!m_thread->wait(1000)) { // 等待1秒
                qWarning() << "GameStateProcessor: 线程停止超时，强制终止";
                m_thread->terminate();
                m_thread->wait(500);
            }
        }
    }
}

void GameStateProcessor::start()
{
    if (m_running) {
        return;
    }

    m_running = true;
    m_processedCount = 0;
    m_lastProcessTime = QDateTime::currentMSecsSinceEpoch();

    qDebug() << "GameStateProcessor: 启动游戏状态处理线程";

    // 在启动线程前，将自己移动到工作线程
    // 这样避免了构造函数中的parent线程冲突
    moveToThread(m_thread);

    m_thread->start();
}

void GameStateProcessor::stop()
{
    if (!m_running) {
        return;
    }
    
    m_running = false;
    
    qDebug() << "GameStateProcessor: 停止游戏状态处理线程";
    
    // 唤醒等待的线程
    m_queueCondition.wakeAll();
    
    // 等待线程结束
    if (m_thread->isRunning()) {
        m_thread->quit();
        m_thread->wait(3000);
    }
}

void GameStateProcessor::setPriority(QThread::Priority priority)
{
    if (m_thread) {
        m_thread->setPriority(priority);
    }
}

void GameStateProcessor::addGameState(const QJsonObject &gameState)
{
    QMutexLocker locker(&m_queueMutex);

    // 统计和限流日志
    static int totalAdded = 0;
    static int totalDropped = 0;
    static int lastLogTime = 0;

    totalAdded++;

    // 每秒打印一次摘要，不再每60帧
    int currentTime = QDateTime::currentSecsSinceEpoch();
    if (currentTime > lastLogTime) {
        qDebug() << "GameStateProcessor摘要: 总接收" << totalAdded
                 << "丢弃" << totalDropped
                 << "队列大小" << m_gameStateQueue.size()
                 << "运行状态" << m_running;
        lastLogTime = currentTime;
    }

    // 只处理game_state_update消息，忽略其他类型
    QString messageType = gameState["type"].toString();
    if (messageType != "game_state_update") {
        qDebug() << "  忽略非游戏状态更新消息:" << messageType;
        return;
    }

    // 限制队列大小，保持最新状态（改为1，只保留最新帧）
    while (m_gameStateQueue.size() >= 1) {
        m_gameStateQueue.dequeue();
        totalDropped++;  // 统计丢弃数量
    }

    m_gameStateQueue.enqueue(gameState);

    if (totalAdded % 60 == 1) {
        qDebug() << "  状态已添加，新队列大小:" << m_gameStateQueue.size();
    }

    // 唤醒处理线程
    m_queueCondition.wakeOne();
}

int GameStateProcessor::queueSize() const
{
    QMutexLocker locker(&m_queueMutex);
    return m_gameStateQueue.size();
}

void GameStateProcessor::processQueue()
{
    if (!m_running) {
        qDebug() << "GameStateProcessor::processQueue: 未运行，跳过";
        return;
    }

    QJsonObject gameState;
    {
        QMutexLocker locker(&m_queueMutex);
        if (m_gameStateQueue.isEmpty()) {
            // 队列为空时不输出日志，避免刷屏
            return;
        }

        // 降噪：每60帧打印一次处理摘要
        if (m_processedCount % 60 == 1) {
            qDebug() << "=== GameStateProcessor::processQueue (每60帧摘要) ===";
            qDebug() << "队列大小:" << m_gameStateQueue.size();
        }

        // 只处理最新的状态，丢弃旧状态
        while (!m_gameStateQueue.isEmpty()) {
            gameState = m_gameStateQueue.dequeue();
        }

        if (m_processedCount % 60 == 1) {
            qDebug() << "取出最新状态，消息类型:" << gameState["type"].toString();
            // 打印消息的关键字段摘要
            QJsonObject data = gameState["data"].toObject();
            if (!data.isEmpty()) {
                QJsonArray snakes = data["snakes"].toArray();
                QJsonArray foods = data["foods"].toArray();
                qDebug() << "snakes数组大小:" << snakes.size() << "foods数组大小:" << foods.size();
            }
        }
    }

    qint64 startTime = QDateTime::currentMSecsSinceEpoch();

    // 解析游戏状态（使用增量解析或传统解析）
    RenderReadyGameData renderData;
    if (m_incrementalParsingEnabled && m_incrementalParser) {
        renderData = m_incrementalParser->parseGameStateIncremental(gameState);
    } else {
        renderData = parseGameState(gameState);
    }

    qint64 processingTime = QDateTime::currentMSecsSinceEpoch() - startTime;
    m_processedCount++;

    // 发送渲染就绪数据（降噪：每60帧打印一次）
    if (m_processedCount % 60 == 1) {
        qDebug() << "=== 解析结果 (每60帧摘要) ===";
        qDebug() << "数据有效:" << renderData.isValid;
        qDebug() << "蛇身长度:" << renderData.snakeBody.size();
        qDebug() << "食物数量:" << renderData.foods.size();
        qDebug() << "存活玩家:" << renderData.alivePlayers;
        qDebug() << "处理时间:" << processingTime << "ms";
    }

    // 强制验证数据有效性
    bool hasValidData = (!renderData.snakeBody.isEmpty() || !renderData.foods.isEmpty());
    if (hasValidData && !renderData.isValid) {
        if (m_processedCount % 60 == 1) {
            qDebug() << "*** 强制设置数据有效 - 蛇身:" << renderData.snakeBody.size() << "食物:" << renderData.foods.size();
        }
        renderData.isValid = true;
    }

    if (renderData.isValid) {
        if (m_processedCount % 60 == 1) {
            qDebug() << "*** GameStateProcessor: 发送renderDataReady信号 ***";
            qDebug() << "  信号数据：蛇身=" << renderData.snakeBody.size() << "食物=" << renderData.foods.size();
        }

        // 确保信号能够正确传递
        emit renderDataReady(renderData);

        if (m_processedCount % 60 == 1) {
            qDebug() << "*** renderDataReady信号已发送 ***";
        }
    } else {
        qWarning() << "*** GameStateProcessor: 数据无效，不发送renderDataReady信号 ***";
        qWarning() << "  原因：isValid=false，蛇身=" << renderData.snakeBody.size() << "食物=" << renderData.foods.size();
    }

    // 更稳健的结束判定：仅基于当前玩家alive且做连续帧确认
    static int consecutiveDeadFrames = 0;
    if (!renderData.alive) {
        consecutiveDeadFrames++;
        if (consecutiveDeadFrames >= 2) { // 连续两帧判定死亡
            emit gameEnded("玩家死亡");
        }
    } else {
        consecutiveDeadFrames = 0;
    }

    // 发送处理统计
    if (m_processedCount % 30 == 0) { // 每30帧发送一次统计
        emit processingStats(m_processedCount, queueSize(), processingTime);
    }
}

RenderReadyGameData GameStateProcessor::parseGameState(const QJsonObject &gameState)
{
    RenderReadyGameData data;
    data.timestamp = QDateTime::currentMSecsSinceEpoch();

    // 解析序列号，按优先级尝试多个字段
    QJsonObject dataObj = gameState["data"].toObject();

    // 优先级1：data.sequence（服务器新增字段）
    data.sequenceNumber = dataObj["sequence"].toVariant().toLongLong();

    // 优先级2：data.qt6_render_info.sequence（Qt6优化字段）
    if (data.sequenceNumber == 0) {
        QJsonObject qt6Info = dataObj["qt6_render_info"].toObject();
        data.sequenceNumber = qt6Info["sequence"].toVariant().toLongLong();
    }

    // 优先级3：data.tick_count
    if (data.sequenceNumber == 0) {
        data.sequenceNumber = dataObj["tick_count"].toVariant().toLongLong();
    }

    // 优先级4：顶层timestamp
    if (data.sequenceNumber == 0) {
        data.sequenceNumber = gameState["timestamp"].toVariant().toLongLong();
    }

    // 最后备用：静态计数器确保递增
    static qint64 fallbackSequence = 1;
    if (data.sequenceNumber == 0) {
        data.sequenceNumber = fallbackSequence++;
    }

    qDebug() << "GameStateProcessor: 开始解析游戏状态";
    qDebug() << "  序列号:" << data.sequenceNumber << "时间戳:" << data.timestamp;
    qDebug() << "  tick_count:" << dataObj["tick_count"].toVariant().toLongLong()
             << "服务器时间戳:" << gameState["timestamp"].toVariant().toLongLong();

    // 继续使用已声明的dataObj
    QJsonArray snakesArray = dataObj["snakes"].toArray();
    QJsonArray foodsArray = dataObj["foods"].toArray();

    qDebug() << "  蛇数量:" << snakesArray.size();
    qDebug() << "  食物数量:" << foodsArray.size();
    
    // 解析游戏信息
    QJsonObject gameInfo = dataObj["game_info"].toObject();
    data.alivePlayers = gameInfo["alive_players"].toInt();
    data.totalPlayers = gameInfo["total_players"].toInt();
    data.gameSpeed = gameInfo["speed_ms"].toInt();
    
    // 解析地图信息
    QJsonObject mapInfo = dataObj["map"].toObject();
    data.mapWidth = mapInfo["width"].toInt();
    data.mapHeight = mapInfo["height"].toInt();
    data.enableWalls = mapInfo["enable_walls"].toBool();

    // 解析障碍物
    QJsonArray obstaclesArray = mapInfo["obstacles"].toArray();
    data.obstacles.clear();
    for (const QJsonValue &obstacleValue : obstaclesArray) {
        QJsonObject obstacle = obstacleValue.toObject();
        int x = obstacle["x"].toInt();
        int y = obstacle["y"].toInt();
        data.obstacles.append(QPoint(x, y));
    }

    qDebug() << "  地图信息: 宽度=" << data.mapWidth << "高度=" << data.mapHeight
             << "启用墙壁=" << data.enableWalls << "障碍物数量=" << data.obstacles.size();
    
    // 解析蛇数据（单人模式取第一条蛇）
    if (!snakesArray.isEmpty()) {
        QJsonObject snakeData = snakesArray[0].toObject();
        data.snakeBody = parseSnakeBody(snakeData);
        data.score = snakeData["score"].toInt();
        data.direction = snakeData["direction"].toInt();
        data.alive = snakeData["alive"].toBool();
        data.playerId = snakeData["player_id"].toString();
        data.isValid = true;

        qDebug() << "  解析蛇数据:";
        qDebug() << "    身体长度:" << data.snakeBody.size();
        qDebug() << "    分数:" << data.score;
        qDebug() << "    方向:" << data.direction;
        qDebug() << "    存活:" << data.alive;
        qDebug() << "    玩家ID:" << data.playerId;
    } else {
        qWarning() << "  没有蛇数据！";
    }
    
    // 解析食物数据
    data.foods = parseFoods(foodsArray);
    qDebug() << "  解析食物数据: 数量" << data.foods.size();

    qDebug() << "GameStateProcessor: 游戏状态解析完成，数据有效:" << data.isValid;

    return data;
}

QList<QPoint> GameStateProcessor::parseSnakeBody(const QJsonObject &snakeData)
{
    QList<QPoint> body;

    // 根据实际服务器数据格式，直接解析body数组
    QJsonArray bodyArray = snakeData["body"].toArray();
    qDebug() << "  开始解析蛇身，body数组大小:" << bodyArray.size();

    for (int i = 0; i < bodyArray.size(); ++i) {
        QJsonValue segment = bodyArray[i];
        QJsonObject segmentObj = segment.toObject();

        // 根据日志显示，每个segment直接包含x,y字段
        if (segmentObj.contains("x") && segmentObj.contains("y")) {
            QPoint bodyPoint(segmentObj["x"].toInt(), segmentObj["y"].toInt());
            body.append(bodyPoint);
            if (i == 0) {
                qDebug() << "  蛇头位置:" << bodyPoint;
            }
        } else if (segmentObj.contains("position")) {
            // 备用：如果有position字段
            QJsonObject pos = segmentObj["position"].toObject();
            if (pos.contains("x") && pos.contains("y")) {
                QPoint bodyPoint(pos["x"].toInt(), pos["y"].toInt());
                body.append(bodyPoint);
                if (i == 0) {
                    qDebug() << "  蛇头位置(position):" << bodyPoint;
                }
            }
        } else {
            qWarning() << "  段" << i << "缺少坐标信息，keys:" << segmentObj.keys();
        }
    }

    qDebug() << "  最终蛇身长度:" << body.size();
    if (!body.isEmpty()) {
        qDebug() << "  蛇头:" << body.first() << "蛇尾:" << body.last();
    }
    return body;
}

QList<QPoint> GameStateProcessor::parseFoods(const QJsonArray &foodsArray)
{
    QList<QPoint> foods;
    
    for (const QJsonValue &food : foodsArray) {
        QJsonObject foodObj = food.toObject();
        QJsonObject position = foodObj["position"].toObject();
        if (position.contains("x") && position.contains("y")) {
            foods.append(QPoint(position["x"].toInt(), position["y"].toInt()));
        }
    }

    return foods;
}

void GameStateProcessor::setIncrementalParsingEnabled(bool enabled)
{
    m_incrementalParsingEnabled = enabled;

    if (m_incrementalParser && !enabled) {
        // 禁用增量解析时重置缓存
        m_incrementalParser->reset();
    }

    qDebug() << "GameStateProcessor: 增量解析" << (enabled ? "已启用" : "已禁用");
}

void GameStateProcessor::getParseStats() const
{
    if (m_incrementalParser) {
        m_incrementalParser->printParseStats();
    }
}
